/*
	Copyright (C) 2008 by Jean-FranÁois Geyelin
	jfgeyelin@gmail.com

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the
	Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "settings.h"
#include "all.h"
#include "globals.h"

#ifdef FMOD_3
#include "FMOD/fmod_errors.h"
#endif

#ifdef FMOD_EX

#endif


MusicThread *MusicThread::instance = NULL;

MusicThread *MusicThread::getInstance(void) {
    if (instance==NULL) {
        instance = new MusicThread();
    }
    return instance;
}

void MusicThread::deleteInstance(void) {
    if (instance==NULL) {
        return;
    }
    delete instance;
    instance = NULL;

}



MusicThread::MusicThread(void) {
    #ifndef NO_MUSIC
	isPlaying = false;
	isFadingOut = false;
	isFadingIn = false;
	hasNextSong = false;
	volume = 20;


    Settings s;
    loadSettings(&s);


	maxVolume = (s.musicVolume*256)/100;

    #ifdef FMOD_3
    music = NULL;
    #endif

    currentChannel = -1;

    #endif
}


MusicThread::~MusicThread(void) {
    #ifndef NO_MUSIC
    abruptelyStopPlayingMusic();
    #endif
}


std::string getFullPath(std::string);

void MusicThread::smoothlyStartPlayingMusic(std::string musicPath) {
    #ifndef NO_MUSIC
    //musicPath = "babacar.mid";


    nextMusicPath = getFullPath(musicPath);

    if (isPlaying) {
        hasNextSong = true;
        isFadingIn = false;
        isFadingOut = true;
    }
    else {
        volume = 0;
        loadAndPlayMusic(nextMusicPath.c_str());
        isFadingOut = false;
        isFadingIn = true;
    }
    #endif
}



void MusicThread::smoothlyStopPlayingMusic(void) {
    #ifndef NO_MUSIC
    if (!isPlaying)
    return;
    isFadingIn = false;
    hasNextSong = false;
    isFadingOut = true;
    #endif
}

void MusicThread::abruptelyStopPlayingMusic(void) {
    #ifndef NO_MUSIC
    if (!isPlaying)
    return;

    #ifdef FMOD_3
    if (!FMUSIC_StopSong(music))
    LOG_ERROR("failed to stop music.\n")
    if (!FMUSIC_FreeSong(music))
    LOG_ERROR("failed to free music.\n")
    else {
        music = NULL;
        TEST_EXECUTION()
    }
    #endif


    isPlaying = false;
    #endif
}

void MusicThread::loadAndPlayMusic(std::string path) {
    #ifndef NO_MUSIC

    #ifdef FMOD_3
    //path = "../sound/babacar.mid";
    music = FMUSIC_LoadSong(path.c_str());
    if (music == NULL) {
        LOG_ERROR("failed (%s) to load music: %s\n",FMOD_ErrorString(FSOUND_GetError()),path.c_str())
    }
    else {
        TEST_EXECUTION()
    }
    if (!FMUSIC_SetLooping(music, 1))
    LOG_ERROR("failed to make the music loop.\n")
    if (!FMUSIC_PlaySong(music))
    LOG_ERROR("failed to play song.\n")
    #endif



    isPlaying = true;
    #endif
}



void MusicThread::setMaxVolume(int v) {
    #ifndef NO_MUSIC

    //FMUSIC_SetReverb(true);
    //PRINTF("vitesse:%i\n",FMUSIC_GetTime(music))

    /*int aa = FMUSIC_SetMasterSpeed(music,1.5);
    if (aa ==-1) {
        LOG_ERROR("failed to change speed: %s\n",FMOD_ErrorString(FSOUND_GetError()))
    }
    else {
        PRINTF("successfully changed speed: %i\n", aa)

    }
    PRINTF("vitesse:%i\n",FMUSIC_GetSpeed(music))
    */


    maxVolume = v;
    if (isPlaying) {
        #ifdef FMOD_3
        FMUSIC_SetMasterVolume(music, (volume*maxVolume)/100);
        #endif
    }
    #endif
}


#define STEP_OF_FADING 1
void MusicThread::update(void) {

    #ifndef NO_MUSIC

    if (!isPlaying)
    return;


    bool volumeHasChanged = isFadingOut || isFadingIn;
    if (isFadingOut) {
        if (volume>0)
        volume-=STEP_OF_FADING;
        if (volume<=0) {
            volume = 0;
            isFadingOut = false;
            TEST_EXECUTION()
            abruptelyStopPlayingMusic();
            TEST_EXECUTION()
            if (hasNextSong) {
                hasNextSong = false;
                isFadingIn = true;
                TEST_EXECUTION()
                loadAndPlayMusic(nextMusicPath.c_str());
                TEST_EXECUTION()
            }
        }
    }


    if (isFadingIn) {
        if (volume<100)
        volume+=STEP_OF_FADING;
        if (volume>=100) {
            volume = 100;
            isFadingIn = false;
        }
    }


    if (volumeHasChanged && isPlaying) {
        #ifdef FMOD_3
        if (!FMUSIC_SetMasterVolume(music, (volume*maxVolume)/100))
        LOG_ERROR("music volume could not be changed.\n")
        #endif
    }

    #endif
}


#undef STEP_OF_FADING

